View Javadoc

1   // ClassUtils.java, created Sun Dec 22 15:45:52 2002 by mcmartin
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
4   package joeq.ClassLib.Common;
5   
6   import joeq.Class.jq_Class;
7   import joeq.Class.jq_CompiledCode;
8   import joeq.Class.jq_Member;
9   import joeq.Memory.StackAddress;
10  import joeq.Runtime.StackCodeWalker;
11  import joeq.Runtime.TypeCheck;
12  
13  /***
14   * ClassUtils
15   *
16   * @author John Whaley <jwhaley@alum.mit.edu>
17   * @version $Id: ClassUtils.java 1456 2004-03-09 22:01:46Z jwhaley $
18   */
19  public abstract class ClassUtils {
20      public static final void checkCallerAccess(jq_Member m, int depth) throws IllegalAccessException {
21          jq_Class field_class = m.getDeclaringClass();
22          if (m.isPublic() && field_class.isPublic()) {
23              // completely public!
24              return;
25          }
26          StackCodeWalker sw = new StackCodeWalker(null, StackAddress.getBasePointer());
27          while (--depth >= 0) sw.gotoNext();
28          jq_CompiledCode cc = sw.getCode();
29          if (cc != null) {
30              jq_Class caller_class = cc.getMethod().getDeclaringClass();
31              if (caller_class == field_class) {
32                  // same class! access allowed!
33                  return;
34              }
35              if (field_class.isPublic() || caller_class.isInSamePackage(field_class)) {
36                  if (m.isPublic()) {
37                      // class is accessible and field is public!
38                      return;
39                  }
40                  if (m.isProtected()) {
41                      if (TypeCheck.isAssignable(caller_class, field_class)) {
42                          // field is protected and field_class is supertype of caller_class!
43                          return;
44                      }
45                  }
46                  if (!m.isPrivate()) {
47                      if (caller_class.isInSamePackage(field_class)) {
48                          // field is package-private and field_class and caller_class are in the same package!
49                          return;
50                      }
51                  }
52              }
53          }
54          throw new IllegalAccessException();
55      }
56  }